use crate::config::app_error::AppResult;
use crate::extension::index::index::indexer::DefaultIndexer;
use crate::extension::index::index::query::query::query_factory::Query;
use crate::extension::index::index::query::query::{BaseQuery, QueryIndexView};
use halo_model::{ExtensionOperator, GVK};
use ordermap::OrderSet;
use std::hash::Hash;

pub(crate) struct Not {
    pub negated_query: Box<Query>,
}

impl Not {
    pub fn new(query: Box<Query>) -> Self {
        Not {
            negated_query: query,
        }
    }
}

impl BaseQuery for Not {
    fn matches(
        &self,
        index_view: &QueryIndexView<DefaultIndexer>,
    ) -> AppResult<OrderSet<String>> {
        let result = self.negated_query.matches(index_view)?;
        let mut all_ids = index_view.get_all_ids()?;
        all_ids.retain(|id| !result.contains(id));
        Ok(all_ids)
    }
}
